<?php

namespace app\admin\service;

use app\admin\dao\UserDao;
use app\admin\model\UM as UM;
use app\common\model\Role;
use app\common\model\User;
use ShidianUtil\Exception\DataNotExistException;
use ShidianUtil\Utils\StringUtil;
use think\exception\ValidateException;

/**
 * Class AdminService
 * @package app\admin\service
 */
class AdminService
{
    private UserDao $userDao;

    public function __construct(UserDao $userDao)
    {
        $this->userDao = $userDao;
    }

    /**
     * 列表
     * @param \app\admin\model\UM|null $user
     * @param int|null $page
     * @param int|null $page_size
     * @return array
     */
    public function index(?UM $user, ?int $page = null, ?int $page_size = null): array
    {
        return $this->userDao->listUsers($page, $page_size);
    }

    /**
     * 查询
     * @param \app\admin\model\UM|null $user
     * @param int $id
     * @return \app\common\model\User
     */
    public function read(?UM $user, int $id): ?User
    {
        return $this->userDao->findUser($id);
    }

    /**
     * 新增
     * @param \app\admin\model\UM $user
     * @param array $params
     * @return  \app\common\model\User
     */
    public function add(UM $user, array $params): User
    {
        if (is_blank($params['username'] ?? null)) {
            throw new ValidateException('请输入用户名');
        }

        if (is_blank($params['password'] ?? null)) {
            throw new ValidateException('请输入密码');
        }

        // 判断权限
        $this->checkSuperAdmin($user, '超级管理员才能新增管理员');

        $this->checkRepeat($params['username']);

        $this->checkRole($params);

        params_enums($params, 'isAdmin', 0, 1);
        $params['salt'] = substr(uniqid(), -6);
        $params['password'] = User::signVerifierHash($params['password'], $params['salt']);
        $params['status'] = 1;

        return $this->userDao->insertActive($params, []);
    }

    /**
     * 更新
     * @param \app\admin\model\UM $user
     * @param int $id
     * @param array $params
     * @return \app\common\model\User
     */
    public function modify(UM $user, int $id, array $params): User
    {
        //这里如果要修改查询，建议把查询就放到这里
        $record = User::field(true)
            ->where('id', $id)
            ->where('roleType', Role::ROLE_TYPE_ADMIN)
            ->find();

        if (is_null($record)) {
            throw new DataNotExistException('该管理员不存在或已被删除');
        }

        $oldRoleId = $record->roleId;

        // 判断权限
        $this->checkSuperAdmin($user, '超级管理员才能修改管理员');

        $this->checkRepeat($params['username'], $record->id);

        $this->checkRole($params);

        if (not_blank($params['password'] ?? null)) {
            $params['password'] = User::signVerifierHash($params['password'], $record->salt);
        }

        params_enums($params, 'isAdmin', 0, 1);

        unset($params['salt']);
        unset($params['token']);

        $allowField = [];
        $this->userDao->updateActive($record, $params, $allowField);

        // 被封禁 || 修改了角色
        if ((isset($params['status']) && $params['status'] == '0') || ($oldRoleId != $record->roleId)) {
            // 立即退出登录
            $record->token = '';
            $record->save();
        }

        return $record;
    }

    /**
     * 删除
     * @param \app\admin\model\UM $user
     * @param int $id
     */
    public function rm(UM $user, int $id): void
    {
        //这里如果要修改查询，建议把查询就放到这里
        $record = User::field(true)
            ->where('id', $id)
            ->where('roleType', Role::ROLE_TYPE_ADMIN)->find();

        if (is_null($record)) {
            return;
        }

        // 判断权限
        $this->checkSuperAdmin($user, '超级管理员才能删除');

        if (!StringUtil::equals($record['roleType'], Role::ROLE_TYPE_ADMIN)) {
            throw new ValidateException('不能删除该角色下账号');
        }

        $this->userDao->deleteModel($record);
    }

    private function checkRepeat($username, $id = null): void
    {
        $record = User::where('username', $username)
            ->when(is_id($id), function ($query) use ($id) {
                $query->where('id', '<>', $id);
            })
            ->find();

        if (!is_null($record)) {
            throw new ValidateException('该用户名已存在');
        }
    }

    /**
     * 非超级管理不能操作超级管理员
     * @param \app\admin\model\UM $user
     * @param $message
     * @return void
     */
    private function checkSuperAdmin(UM $user, $message): void
    {
        if ($user->isAdmin != '1') {
            throw new ValidateException($message);
        }
    }

    private function checkRole(&$params)
    {
        $roleId = $params['roleId'] ?? null;

        if (!is_id($roleId)) {
            return;
        }

        $role = Role::where('id', $roleId)
            ->find();

        if (!$role) {
            unset($params['roleId']);
        }

        if (!StringUtil::equals($role['roleType'], Role::ROLE_TYPE_ADMIN)) {
            throw new ValidateException('不能选择该角色类型');
        }

        $params['roleType'] = $role['roleType'];
    }
}
